Product : ISaGRAF V3
Date : 5-March-1996
File : WDKcom2.ISDK_COM.dll implementation using a timer.htm
Subject : ISDK_COM.dll implementation using a timer
Keywords: ISDK_COM - postmessage - isdk_com_send - timer
____________________________________________________________________
Below is the source code of a sample ISDK_COM program. It uses a
timer to delay the postmessage call after isdk_com_send is
processed. Don't care about the hard coded frames built in
isdk_com_receive routine. Just focus on the child window / timer
mechanism. You can use the same timer management in your software.
/*****************************************************************
File : ISDK_COM.c
Description : user defined communications
hard coded connection frames
This examples uses a Timer linked to a child window, to post an
"awake" message to the debugger main window.
Only two frames of the ISaGRAF protocols are handled. They are
hard coded in the isdk_com_receive routine. DONT CARE ABOUT THIS.
The aim of this example is to demonstrate how to use a TIMER and
a CHILD window.
*****************************************************************/
#include "windows.h"
#include "memory.h" /* required for memset */
/* exports: child window callback procedure */
long CALLBACK childwndproc (HWND, UINT, WPARAM, LPARAM);
/* YOU ABSOLUTELY NEED TO ADD THE NAME OF THIS PROCEDURE
IN THE LIST OF EXPORTS IN FILE ISDK_COM.DEF */
/* static data / defines */
#define IDT_TIMER 14 /* timer identifier */
#define PERIOD 100 /* timer duration (after SEND) */
static HWND CHWND; /* child window handle */
static HINSTANCE HINST; /* module (dll) code handle */
static WORD TMRID; /* timer identifier */
/* DLL main entry point */
int FAR PASCAL LibMain (HANDLE hModule, WORD wDataSeg,
WORD cbHeapSize, LPSTR lpszCmdLine)
{
HINST = hModule; /* store module handle to create child window*/
return 1;
}
/* DLL ending point */
int FAR PASCAL WEP (int bSystemExit)
{
return(1);
}
/* dont care about this: just used to hard code the answer */
static WORD DBGMSG;
static HWND WNDDBG;
static BYTE SLAVE;
static BYTE REQ;
static BYTE NT;
int FAR PASCAL isdk_com_isdefined (void)
{
return (1);
}
int FAR PASCAL isdk_com_getname (LPSTR buffer)
{
lstrcpy (buffer, "TestCnx");
return (1);
}
int FAR PASCAL isdk_com_setup (HWND hwndParent, LPSTR projectdir)
{
MessageBox (hwndParent,
"No other parameter needed",
"Test Connection",
MB_OK);
return (1);
}
/*
Child window class registration and child window creation must be
achieved in the ISDK_COM_DEFMESSAGE procedure.
*/
int FAR PASCAL isdk_com_defmessage (HWND hwndDebug,
WORD wakeup_message)
{
WNDCLASS pWndClass;
/* store debugger information */
DBGMSG = wakeup_message;
WNDDBG = hwndDebug;
/* register child window class */
memset (&pWndClass, 0, sizeof (pWndClass));
pWndClass.lpfnWndProc = childwndproc;
pWndClass.hInstance = HINST;
pWndClass.hbrBackground = COLOR_WINDOW+1;
pWndClass.lpszClassName = "ISDK_COM_CHILD";
if (!RegisterClass (&pWndClass)) {
MessageBox (DBGMSG, "Cannot register child window class",
"ISDK_COM Error", MB_OK);
return (0);
}
/* create child window - when everything is running, it is better
to remove the "WS_VISIBLE" attribute. It is not worth to destroy
this window, as child windows are automatically destroyed with
their parent window */
CHWND = CreateWindow ("ISDK_COM_CHILD", /* window class name */
"ISDK com", /* no title */
WS_CHILD|WS_BORDER|WS_VISIBLE|WS_CAPTION,
300, 3, 100, 20,
WNDDBG, /* parent window: debugger */
(UINT)-1,
HINST, NULL);
if (CHWND == NULL) {
MessageBox (DBGMSG, "Cannot create child window",
"ISDK_COM Error", MB_OK);
return (0);
}
return (1);
}
int FAR PASCAL isdk_com_open (WORD isagraf_slave, LPSTR projectdir)
{
return (1);
}
/* THIS IS THE CHILD WINDOW CALLBACK PROCEDURE */
long CALLBACK childwndproc (HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
switch (message) {
case WM_PAINT :
BeginPaint (hWnd, &ps);
EndPaint (hWnd, &ps);
break;
case WM_TIMER :
/* timer event: normally you write the following algorithm:
if (data_is_ready) {
post message to debugger window
kill timer (no more needed)
}
else {
nothing: wait for next timer event
}
*/
if (wParam == IDT_TIMER) {
PostMessage (WNDDBG, DBGMSG, 0, 0L);
KillTimer (CHWND, IDT_TIMER);
TMRID = 0;
}
break;
default :
return (DefWindowProc (hWnd, message, wParam, lParam));
}
return (NULL);
}
int FAR PASCAL isdk_com_close (void)
{
/* you dont need to destroy child window
Windows does it for you */
return (1);
}
int FAR PASCAL isdk_com_send (LPBYTE snd_data, WORD snd_size)
{
SLAVE = *snd_data;
NT = snd_data[2];
if (snd_data[1] == 0x41
&& snd_data[5] == 0x0a
&& snd_data[6] == 0x00)
REQ = 1;
else if (snd_data[1] == 0x43 && snd_data[5] == 0x35)
REQ = 2;
else REQ = 0;
if (REQ) {
/* when data is sent, set the timer: the whild window callback
procedure will be awaken with WM_TIMER message */
TMRID = SetTimer (CHWND, IDT_TIMER, PERIOD, NULL);
}
return ((int)REQ);
}
int FAR PASCAL isdk_com_receive (LPWORD errcode, LPWORD rcv_size,
LPBYTE rcv_data)
{
/* isdk_com_receive is called only when data is ready, according to
the following sequence:
1- debugger invokes isdk_com_send:
data is sent
timer is set
2- child window receives wm_timer message
wait for the next message if reveiced data is not ready
3- child window receives wm_timer message when rcv data is ready
kills the timer
post notification message to the debugger
4- debugger invokes isdk_com_receive to get receive data
*/
/* the following code just builds a hard coded answer for the two
main frames exchanged when debugger starts */
switch (REQ) {
case 1 : rcv_data[0] = SLAVE;
rcv_data[1] = 0x41;
rcv_data[2] = NT;
rcv_data[3] = 0;
rcv_data[4] = 0x13;
rcv_data[5] = 0x0a;
rcv_data[6] = 0;
rcv_data[7] = 0;
rcv_data[8] = 0;
wsprintf (&(rcv_data[9]), "%c%s%c%s%c",
3, "1.60", 8, "Test_Cnx", 0);
*errcode = 0;
*rcv_size = 24;
break;
case 2 : rcv_data[0] = SLAVE;
rcv_data[1] = 0x43;
rcv_data[2] = NT;
rcv_data[3] = 0;
rcv_data[4] = 9;
rcv_data[5] = 0x35;
rcv_data[6] = 0;
rcv_data[7] = 0;
rcv_data[8] = 0;
rcv_data[9] = 0;
rcv_data[10] = 0;
rcv_data[11] = 0;
rcv_data[12] = 0;
rcv_data[13] = 0;
*errcode = 0;
*rcv_size = 14;
break;
default: *errcode = 1;
*rcv_size = 0;
break;
}
return (1);
}
int FAR PASCAL isdk_com_abort (void)
{
/* kill the timer if it exists */
return (1);
}
____________________________________________________________________
Copyright © 1996-2009 ICS Triplex ISaGRAF Inc. All rights reserved.